#include <iostream>
#include <dlfcn.h>
#include "../../include/cryptoki_ext.h"
#include "../../include/auxiliary.h"
#include "GetPinInfo.h"

using namespace std;

GetPinInfo::GetPinInfo()
{
	m_hPkiLib = NULL;
	m_pSlotList = NULL;
	m_pPinInfo = NULL;
	m_pAuxFunc = NULL;
}

GetPinInfo::~GetPinInfo()
{
	if(m_pSlotList)
	{
		delete[] m_pSlotList;
	}
	if(m_pPinInfo)
	{
		delete m_pPinInfo;
	}
}

CK_RV GetPinInfo::Connect()
{
	CK_RV rv;
	rv = C_Initialize(NULL_PTR);
	if(CKR_OK != rv)
	{
		cout<<"Initialize PKCS#11 fault"<<endl;
		return rv;
	}
	CK_ULONG ulCount;
	rv = C_GetSlotList(TRUE, NULL_PTR, &ulCount);
	if(CKR_OK != rv)
	{
		cout<<"Get slot list fault"<<endl;
		return rv;
	}
	if(0 >= ulCount)
	{
		cout<<"Make sure you have inserted token"<<endl;
		return CKR_GENERAL_ERROR;
	}
	m_pSlotList = (CK_SLOT_ID_PTR)new CK_SLOT_ID[ulCount];
	if(NULL == m_pSlotList)
	{
		cout<<"Can't allocate enough memeroy"<<endl;
		return CKR_GENERAL_ERROR;
	}
	rv = C_GetSlotList(TRUE, m_pSlotList, &ulCount);
	if(CKR_OK != rv)
	{
		cout<<"Can't get slot list"<<endl;
		return rv;
	}else {
		cout<<"Connect OK!"<<endl;
		return rv;
	}
}

CK_RV GetPinInfo::Get()
{
	CK_RV rv;
	m_hPkiLib = dlopen("../../../redist/libcastle.so.1.0.0", RTLD_NOW);
	if(NULL_PTR == m_hPkiLib)
	{
		cout<<"Can't load lib \"libcastle.so.1.0.0\""<<endl;
		return CKR_GENERAL_ERROR;
	}
	EP_GetAuxFunctionList pE_GetAuxFunctionList = (EP_GetAuxFunctionList)dlsym(m_hPkiLib,"E_GetAuxFunctionList");
	if(NULL_PTR == pE_GetAuxFunctionList)
	{
		dlclose(m_hPkiLib);
		cout<<"Can't get function list"<<endl;
		return CKR_GENERAL_ERROR;
	}
	rv = pE_GetAuxFunctionList(&m_pAuxFunc);
	if(CKR_OK != rv)
	{
		dlclose(m_hPkiLib);
		cout<<"Can't get function list"<<endl;
		return CKR_GENERAL_ERROR;
	}
	m_pPinInfo = (AUX_PIN_INFO_PTR)new AUX_PIN_INFO;
	rv = ((EP_GetPinInfo)(m_pAuxFunc->pFunc[EP_GET_PIN_INFO]))(m_pSlotList[0],m_pPinInfo);
	if(CKR_OK != rv)
	{
		dlclose(m_hPkiLib);
		cout<<"Get PIN info fault"<<endl;
		return rv;
	} else {
		int aTemp = m_pPinInfo->bSOPinMaxRetries; 
		cout<<"SOPinMaxRetries is :   "<<aTemp<<endl;
		aTemp = m_pPinInfo->bSOPinCurCounter;
		cout<<"SOPinCurCounter is :   "<<aTemp<<endl;
		aTemp = m_pPinInfo->bUserPinMaxRetries;
		cout<<"UserPinMaxRetries is : "<<aTemp<<endl;
		aTemp = m_pPinInfo->bUserPinCurCounter;
		cout<<"UserPinCurCounter is : "<<aTemp<<endl;
		dlclose(m_hPkiLib);
		return rv;
	}
}
